#ifndef DATASOURCE_H
#define DATASOURCE_H

#include <fstream>
#include <string>
#include <vector>

class DataSource {
public:
    virtual ~DataSource() {}

    /**
     * Efficiently return a stream instance that will read the data source file's
     * contents directly from the data source. For example, this will read a file
     * within an MPQ or CASC storage without extracting it.
     *
     * @param filepath
     * @return
     * @throws std::runtime_error
     */
    virtual std::ifstream getResourceAsStream(const std::string& filepath) throw(std::runtime_error);

    /**
     * Inefficiently copy a file from the data source onto the Hard Drive of the
     * computer, and then return a java File instance pointed at the file.
     *
     * @param filepath
     * @return
     * @throws std::runtime_error
     */
    virtual void* getFile(const std::string& filepath) throw(std::runtime_error);

    /**
     * Returns a directory from a FolderDataSource, otherwise returns null
     *
     * @param filepath
     * @return
     * @throws std::runtime_error
     */
    virtual void* getDirectory(const std::string& filepath) throw(std::runtime_error);

    /**
     * Reads the contents of a file into a ByteBuffer.
     *
     * @param path The path to the file to read.
     * @return A ByteBuffer containing the contents of the file.
     * @throws std::runtime_error
     */
    virtual void* read(const std::string& path) throw(std::runtime_error);

    /**
     * Returns true if the data source contains a valid entry for a particular file.
     * Some data sources (MPQs) may contain files for which this returns true, even
     * though they cannot list the file in their Listfile.
     *
     * @param filepath
     * @return True if the data source contains a valid entry for the file.
     */
    virtual bool has(const std::string& filepath);

    /**
     * Returns a vector of strings representing the contents of the Listfile.
     *
     * @return A vector of strings, or an empty vector if no list is provided.
     */
    virtual std::vector<std::string> getListfile();

    /**
     * Closes the data source. This method should be called when you are finished
     * using a particular data source.
     *
     * @throws std::runtime_error
     */
    virtual void close() throw(std::runtime_error);
};

#endif // DATASOURCE_H
